package com.ruoyi.rabbitmq.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.rabbitmq.service.BusinessMessageService;
import com.ruoyi.rabbitmq.service.MessagePublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * RabbitMQ测试Controller
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/rabbitmq/test")
@ConditionalOnProperty(name = "spring.rabbitmq.enabled", havingValue = "true", matchIfMissing = true)
public class RabbitMQTestController extends BaseController
{
    @Autowired
    private MessagePublisher messagePublisher;

    @Autowired
    private BusinessMessageService businessMessageService;

    @Value("${spring.rabbitmq.host:localhost}")
    private String host;

    @Value("${spring.rabbitmq.port:5672}")
    private int port;

    @Value("${spring.rabbitmq.username:guest}")
    private String username;

    @Value("${spring.rabbitmq.virtual-host:/}")
    private String virtualHost;

    @Value("${spring.rabbitmq.connection-timeout:5000}")
    private int connectionTimeout;

    @Value("${spring.rabbitmq.heartbeat:60}")
    private int heartbeat;

    @Value("${spring.rabbitmq.automatic-recovery-enabled:true}")
    private boolean automaticRecoveryEnabled;

    @Value("${spring.rabbitmq.network-recovery-interval:5000}")
    private int networkRecoveryInterval;

    @Value("${spring.rabbitmq.publisher-confirms:true}")
    private boolean publisherConfirms;

    @Value("${spring.rabbitmq.publisher-returns:true}")
    private boolean publisherReturns;

    @Value("${spring.rabbitmq.concurrent-consumers:1}")
    private int concurrentConsumers;

    @Value("${spring.rabbitmq.max-concurrent-consumers:10}")
    private int maxConcurrentConsumers;

    @Value("${spring.rabbitmq.prefetch-count:1}")
    private int prefetchCount;

    /**
     * 查看RabbitMQ配置信息
     */
    @GetMapping("/config")
    public AjaxResult getRabbitMQConfig()
    {
        Map<String, Object> config = new HashMap<>();
        config.put("host", host);
        config.put("port", port);
        config.put("username", username);
        config.put("virtualHost", virtualHost);
        config.put("connectionTimeout", connectionTimeout);
        config.put("heartbeat", heartbeat);
        config.put("automaticRecoveryEnabled", automaticRecoveryEnabled);
        config.put("networkRecoveryInterval", networkRecoveryInterval);
        config.put("publisherConfirms", publisherConfirms);
        config.put("publisherReturns", publisherReturns);
        config.put("concurrentConsumers", concurrentConsumers);
        config.put("maxConcurrentConsumers", maxConcurrentConsumers);
        config.put("prefetchCount", prefetchCount);
        
        return AjaxResult.success("RabbitMQ配置信息", config);
    }

    /**
     * 简单测试接口 - 无需权限
     */
    @GetMapping("/simple")
    public AjaxResult simpleTest()
    {
        return AjaxResult.success("RabbitMQ测试接口正常");
    }

    /**
     * 简单发送直连消息 - 无需权限
     */
    @PostMapping("/simple/send/direct")
    public AjaxResult simpleSendDirectMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            if (content == null)
            {
                content = "测试消息 " + System.currentTimeMillis();
            }
            String messageId = messagePublisher.sendDirectMessage(content);
            return AjaxResult.success("直连消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("直连消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 简单发送主题消息 - 无需权限
     */
    @PostMapping("/simple/send/topic")
    public AjaxResult simpleSendTopicMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String routingKey = (String) params.get("routingKey");
            if (content == null)
            {
                content = "测试主题消息 " + System.currentTimeMillis();
            }
            if (routingKey == null || routingKey.isEmpty())
            {
                routingKey = "test.topic";
            }
            String messageId = messagePublisher.sendTopicMessage(content, routingKey);
            return AjaxResult.success("主题消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("主题消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 简单发送扇形消息 - 无需权限
     */
    @PostMapping("/simple/send/fanout")
    public AjaxResult simpleSendFanoutMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            if (content == null)
            {
                content = "测试扇形消息 " + System.currentTimeMillis();
            }
            String messageId = messagePublisher.sendFanoutMessage(content);
            return AjaxResult.success("扇形消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("扇形消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送直连消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送直连消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/direct")
    public AjaxResult testSendDirectMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String messageId = messagePublisher.sendDirectMessage(content);
            return AjaxResult.success("直连消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("直连消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送主题消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送主题消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/topic")
    public AjaxResult testSendTopicMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String routingKey = (String) params.get("routingKey");
            String messageId = messagePublisher.sendTopicMessage(content, routingKey);
            return AjaxResult.success("主题消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("主题消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送扇形消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送扇形消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/fanout")
    public AjaxResult testSendFanoutMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String messageId = messagePublisher.sendFanoutMessage(content);
            return AjaxResult.success("扇形消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("扇形消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送延迟消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送延迟消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/delay")
    public AjaxResult testSendDelayMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            Long delayMillis = Long.valueOf(params.get("delayMillis").toString());
            String messageId = messagePublisher.sendRetryMessage(content, delayMillis);
            return AjaxResult.success("延迟消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("延迟消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送用户注册消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送用户注册消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/user-registration")
    public AjaxResult testSendUserRegistrationMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Long userId = Long.valueOf(params.get("userId").toString());
            String username = (String) params.get("username");
            String email = (String) params.get("email");
            
            businessMessageService.sendUserRegistrationMessage(userId, username, email);
            return AjaxResult.success("用户注册消息发送成功");
        }
        catch (Exception e)
        {
            return AjaxResult.error("用户注册消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送订单创建消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送订单创建消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/order-created")
    public AjaxResult testSendOrderCreatedMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Long orderId = Long.valueOf(params.get("orderId").toString());
            Long userId = Long.valueOf(params.get("userId").toString());
            Double amount = Double.valueOf(params.get("amount").toString());
            
            businessMessageService.sendOrderCreatedMessage(orderId, userId, amount);
            return AjaxResult.success("订单创建消息发送成功");
        }
        catch (Exception e)
        {
            return AjaxResult.error("订单创建消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送邮件通知消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送邮件通知消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/email-notification")
    public AjaxResult testSendEmailNotificationMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            String to = (String) params.get("to");
            String subject = (String) params.get("subject");
            String content = (String) params.get("content");
            
            businessMessageService.sendEmailNotificationMessage(to, subject, content);
            return AjaxResult.success("邮件通知消息发送成功");
        }
        catch (Exception e)
        {
            return AjaxResult.error("邮件通知消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送系统通知消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送系统通知消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/system-notification")
    public AjaxResult testSendSystemNotificationMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            String title = (String) params.get("title");
            String content = (String) params.get("content");
            String[] targetUsers = ((String) params.get("targetUsers")).split(",");
            
            businessMessageService.sendSystemNotificationMessage(title, content, targetUsers);
            return AjaxResult.success("系统通知消息发送成功");
        }
        catch (Exception e)
        {
            return AjaxResult.error("系统通知消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送定时任务消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送定时任务消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/scheduled-task")
    public AjaxResult testSendScheduledTaskMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            String taskName = (String) params.get("taskName");
            Object taskData = params.get("taskData");
            Long delayMillis = Long.valueOf(params.get("delayMillis").toString());
            
            businessMessageService.sendScheduledTaskMessage(taskName, taskData, delayMillis);
            return AjaxResult.success("定时任务消息发送成功");
        }
        catch (Exception e)
        {
            return AjaxResult.error("定时任务消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 测试发送死信消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "测试发送死信消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/dead-letter")
    public AjaxResult testSendDeadLetterMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            businessMessageService.sendDeadLetterMessage(content);
            return AjaxResult.success("死信消息发送成功");
        }
        catch (Exception e)
        {
            return AjaxResult.error("死信消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 批量测试消息发送
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:test:send')")
    @Log(title = "批量测试消息发送", businessType = BusinessType.INSERT)
    @PostMapping("/send/batch")
    public AjaxResult testBatchSendMessages(@RequestBody Map<String, Object> params)
    {
        try
        {
            Integer count = Integer.valueOf(params.get("count").toString());
            String messageType = (String) params.get("messageType");
            
            Map<String, Object> results = new HashMap<>();
            
            for (int i = 0; i < count; i++)
            {
                String content = "测试消息 " + (i + 1);
                String messageId = "";
                
                switch (messageType)
                {
                    case "direct":
                        messageId = messagePublisher.sendDirectMessage(content);
                        break;
                    case "topic":
                        messageId = messagePublisher.sendTopicMessage(content, "test.topic." + i);
                        break;
                    case "fanout":
                        messageId = messagePublisher.sendFanoutMessage(content);
                        break;
                    case "delay":
                        messageId = messagePublisher.sendRetryMessage(content, 5000);
                        break;
                    default:
                        return AjaxResult.error("不支持的消息类型：" + messageType);
                }
                
                results.put("消息" + (i + 1), messageId);
            }
            
            return AjaxResult.success("批量消息发送成功", results);
        }
        catch (Exception e)
        {
            return AjaxResult.error("批量消息发送失败：" + e.getMessage());
        }
    }
} 